//
//  ZButton.m
//
//  Created by ZhàoYǒng on 31/10/2017.
//  Copyright © 2017 ZhàoYǒng. All rights reserved.
//

#import "ZButton.h"
#import <Masonry/Masonry.h>

@interface ZButtonState : NSObject

@property (nonatomic, assign) UIControlState state;
@property (nonatomic,   copy) NSString *title;
@property (nonatomic, strong) UIColor  *titleColor;
@property (nonatomic, strong) UIFont   *font;
@property (nonatomic, strong) UIImage  *image;
@property (nonatomic, strong) UIImage  *backgroundImage;

@end

@implementation ZButtonState

+ (instancetype)normal {
    ZButtonState *state = [[ZButtonState alloc] init];
    state.state = UIControlStateNormal;
    state.font = [UIFont systemFontOfSize:17.f];
    state.titleColor = UIColor.blackColor;
    state.title = nil;
    state.image = nil;
    state.backgroundImage = nil;
    return state;
}

+ (instancetype)highlighted {
    ZButtonState *state = [[ZButtonState alloc] init];
    state.state = UIControlStateHighlighted;
    state.titleColor = [UIColor.blackColor colorWithAlphaComponent:0.5f];
    state.font = nil;
    state.title = nil;
    state.image = nil;
    state.backgroundImage = nil;
    return state;
}

+ (instancetype)selected {
    ZButtonState *state = [[ZButtonState alloc] init];
    state.state = UIControlStateSelected;
    state.titleColor = nil;
    state.font = nil;
    state.title = nil;
    state.image = nil;
    state.backgroundImage = nil;
    return state;
}

@end

@interface ZButton ()

@property (nonatomic, strong) ZButtonState *stateNormal;
@property (nonatomic, strong) ZButtonState *stateHighli;
@property (nonatomic, strong) ZButtonState *stateSelect;

@property (nonatomic, assign) ZButtonImagePosition position;
@property (nonatomic, assign) CGFloat margin;
@property (nonatomic, strong) UIColor *imageTintColor;

@property (nonatomic, strong) UIView *container;
@property (nonatomic, strong) UILabel *titleLabel;
@property (nonatomic, strong) UIImageView *imageView;
@property (nonatomic, strong) UIImageView *backgroundImageView;
@property (nonatomic, strong) UIView   *badgeView;

@end

@implementation ZButton

- (instancetype)initWithImagePosition:(ZButtonImagePosition)position {
    self = [super init];
    if (self) {
        [self initialization:position];
    }
    return self;
}

- (void)initialization:(ZButtonImagePosition)position {
    
    self.backgroundColor = UIColor.clearColor;
    self.clipsToBounds = NO;
    
    _stateNormal = ZButtonState.normal;
    _stateHighli = ZButtonState.highlighted;
    _stateSelect = ZButtonState.selected;
    
    _position = position;
    _margin = 5.f;
    _imageTintColor = UIColor.blueColor;
    
    _container = [[UIView alloc] init];
    _container.backgroundColor = UIColor.clearColor;
    _container.userInteractionEnabled = NO;
    _container.clipsToBounds = NO;
    [self addSubview:_container];
    [_container mas_makeConstraints:^(MASConstraintMaker *make) {
        make.left.top.greaterThanOrEqualTo(self);
        make.right.bottom.lessThanOrEqualTo(self);
        make.center.equalTo(self);
    }];
    
}

#pragma mark - Getter

- (UILabel *)titleLabel {
    if (!_titleLabel) {
        _titleLabel = [[UILabel alloc] init];
        _titleLabel.textColor = _stateNormal.titleColor;
        _titleLabel.font = _stateNormal.font;
        _titleLabel.text = _stateNormal.title;
    }
    return _titleLabel;
}

- (UIImageView *)imageView {
    if (!_imageView) {
        _imageView = [[UIImageView alloc] init];
        _imageView.tintColor = _imageTintColor;
        _imageView.contentMode = UIViewContentModeScaleAspectFit;
        _imageView.image = _stateNormal.image;
    }
    return _imageView;
}

- (UIImageView *)backgroundImageView {
    if (!_backgroundImageView) {
        _backgroundImageView = [[UIImageView alloc] init];
        _backgroundImageView.tintColor = _imageTintColor;
        _backgroundImageView.contentMode = UIViewContentModeScaleAspectFill;
        _backgroundImageView.image = _stateNormal.backgroundImage;
    }
    return _backgroundImageView;
}

- (NSString *)titleForState:(UIControlState)state {
    return [self certainState:state].title;
}

- (UIImage *)imageForState:(UIControlState)state {
    return [self certainState:state].image;
}

- (UIImage *)backgroundImageForState:(UIControlState)state {
    return [self certainState:state].backgroundImage;
}

- (UIView *)badgeView {
    if (!_badgeView) {
        _badgeView = [[UIView alloc] init];
        _badgeView.layer.cornerRadius = 4.f;
        _badgeView.backgroundColor = UIColor.redColor;
        _badgeView.clipsToBounds = YES;
    }
    return _badgeView;
}

#pragma mark - Setter

- (void)setHighlighted:(BOOL)highlighted {
    [super setHighlighted:highlighted];
    ZButtonState *curState = [self certainState:self.state];
    ZButtonState *state = highlighted ? _stateHighli : curState;
    _imageView.image = state.image ?: _stateNormal.image;
    _backgroundImageView.image = state.backgroundImage ?: _stateNormal.backgroundImage;
    _titleLabel.textColor = state.titleColor ?: _stateNormal.titleColor;
    _titleLabel.font = state.font ?: _stateNormal.font;
    _titleLabel.text = state.title ?: _stateNormal.title;
}

- (void)setSelected:(BOOL)selected {
    [super setSelected:selected];
    ZButtonState *state = selected ? _stateSelect : _stateNormal;
    _imageView.image = state.image ?: _stateNormal.image;
    _backgroundImageView.image = state.backgroundImage ?: _stateNormal.backgroundImage;
    _titleLabel.textColor = state.titleColor ?: _stateNormal.titleColor;
    _titleLabel.font = state.font ?: _stateNormal.font;
    _titleLabel.text = state.title ?: _stateNormal.title;
}

- (void)setMargin:(CGFloat)margin {
    _margin = margin;
}

- (void)setImageTintColor:(UIColor *)tintColor {
    _imageTintColor = tintColor;
    _imageView.tintColor = tintColor;
    _backgroundImageView.tintColor = tintColor;
}

- (void)setTitle:(NSString *)title state:(UIControlState)state {
    [self certainState:state].title = title;
    if (!_titleLabel) {
        [self.container addSubview:self.titleLabel];
        if (_imageView) {
            [_titleLabel mas_makeConstraints:^(MASConstraintMaker *make) {
                make.left.top.greaterThanOrEqualTo(self.container);
                make.right.bottom.lessThanOrEqualTo(self.container);
                switch (self.position) {
                    case ZButtonImagePositionTop:
                        make.top.equalTo(self.imageView.mas_bottom).offset(self.margin);
                        make.centerX.equalTo(self.container);
                        make.centerX.equalTo(self.imageView);
                        break;
                    case ZButtonImagePositionBottom:
                        make.bottom.equalTo(self.imageView.mas_top).offset(-self.margin);
                        make.centerX.equalTo(self.container);
                        make.centerX.equalTo(self.imageView);
                        break;
                    case ZButtonImagePositionLeft:
                        make.left.equalTo(self.imageView.mas_right).offset(self.margin);
                        make.centerY.equalTo(self.container);
                        make.centerY.equalTo(self.imageView);
                        break;
                    case ZButtonImagePositionRight:
                        make.right.equalTo(self.imageView.mas_left).offset(-self.margin);
                        make.centerY.equalTo(self.container);
                        make.centerY.equalTo(self.imageView);
                        break;
                    default: break;
                }
            }];
        } else {
            [_titleLabel mas_makeConstraints:^(MASConstraintMaker *make) {
                make.left.top.greaterThanOrEqualTo(self.container);
                make.right.bottom.lessThanOrEqualTo(self.container);
            }];
        }
    }
    if (self.state == state) {
        self.titleLabel.text = title;
    }
}

- (void)setTitleColor:(UIColor *)color state:(UIControlState)state {
    [self certainState:state].titleColor = color;
    if (state == UIControlStateNormal) {
        [self certainState:UIControlStateHighlighted].titleColor = [_stateNormal.titleColor colorWithAlphaComponent:0.5f];
    }
    if (self.state == state) {
        _titleLabel.textColor = [self certainState:state].titleColor;
    }
}

- (void)setFont:(UIFont *)font state:(UIControlState)state {
    [self certainState:state].font = font;
    if (self.state == state) {
        _titleLabel.font = font;
    }
}

- (void)setImage:(UIImage *)image state:(UIControlState)state {
    if (self.position == ZButtonImagePositionNone) return;
    [self certainState:state].image = image;
    if (!_imageView) {
        [self.container addSubview:self.imageView];
        if (_titleLabel) {
            [_imageView mas_makeConstraints:^(MASConstraintMaker *make) {
                make.left.top.greaterThanOrEqualTo(self.container);
                make.right.bottom.lessThanOrEqualTo(self.container);
                switch (self.position) {
                    case ZButtonImagePositionTop:
                        make.bottom.equalTo(self.titleLabel.mas_top).offset(-self.margin);
                        make.centerX.equalTo(self.container);
                        make.centerX.equalTo(self.titleLabel);
                        break;
                    case ZButtonImagePositionBottom:
                        make.top.equalTo(self.titleLabel.mas_bottom).offset(self.margin);
                        make.centerX.equalTo(self.container);
                        make.centerX.equalTo(self.titleLabel);
                        break;
                    case ZButtonImagePositionLeft:
                        make.right.equalTo(self.titleLabel.mas_left).offset(-self.margin);
                        make.centerY.equalTo(self.container);
                        make.centerY.equalTo(self.titleLabel);
                        break;
                    case ZButtonImagePositionRight:
                        make.left.equalTo(self.titleLabel.mas_right).offset(self.margin);
                        make.centerY.equalTo(self.container);
                        make.centerY.equalTo(self.titleLabel);
                        break;
                    default: break;
                }
            }];
        } else {
            [_imageView mas_makeConstraints:^(MASConstraintMaker *make) {
                make.left.top.greaterThanOrEqualTo(self.container);
                make.right.bottom.lessThanOrEqualTo(self.container);
            }];
        }
    }
    [_imageView setContentCompressionResistancePriority:UILayoutPriorityRequired forAxis:UILayoutConstraintAxisVertical];
    [_imageView setContentCompressionResistancePriority:UILayoutPriorityRequired forAxis:UILayoutConstraintAxisHorizontal];
    if (self.state == state) {
        self.imageView.image = image;
    }
}

- (void)setBackgroundImage:(UIImage *)image state:(UIControlState)state {
    [self certainState:state].backgroundImage = image;
    if (!_backgroundImageView) {
        [self.container insertSubview:self.backgroundImageView atIndex:0];
        [_backgroundImageView mas_makeConstraints:^(MASConstraintMaker *make) {
            make.edges.equalTo(self.container);
        }];
    }
    if (self.state == state) {
        self.backgroundImageView.image = image;
    }
}

- (void)setBadge:(NSUInteger)badge {
    if (badge > 0) {
        [self.container addSubview:self.badgeView];
        if (_imageView) {
            [self.badgeView mas_makeConstraints:^(MASConstraintMaker *make) {
                make.centerX.equalTo(self.imageView.mas_right);
                make.centerY.equalTo(self.imageView.mas_top);
                make.width.height.equalTo(@8.f);
            }];
        } else if (_titleLabel) {
            [self.badgeView mas_makeConstraints:^(MASConstraintMaker *make) {
                make.centerX.equalTo(self.titleLabel.mas_right);
                make.centerY.equalTo(self.titleLabel.mas_top);
                make.width.height.equalTo(@8.f);
            }];
        } else {
            [self.badgeView mas_makeConstraints:^(MASConstraintMaker *make) {
                make.centerX.equalTo(self.container.mas_right);
                make.centerY.equalTo(self.container.mas_top);
                make.width.height.equalTo(@8.f);
            }];
        }
    } else {
        [self.badgeView removeFromSuperview];
    }
}

- (ZButtonState *)certainState:(UIControlState)state {
    switch (state) {
        case UIControlStateHighlighted: return _stateHighli;
        case UIControlStateSelected:    return _stateSelect;
        case (UIControlStateHighlighted + UIControlStateSelected): return _stateSelect;
        default: return _stateNormal;
    }
}

@end
